<?php	

class AGIDB {
  // Database Variables from [globals]. Self explanatory.
  private $dbhost;
  public $dbuser;
  public $dbpass;
  private $dbfile;
  public $dbname;

  // sqlite3 needs some global variables to handle returns. They aren't needed
  // to be defined here, but be aware that they are used by this module.

  /* global $sql3holderAssoc;	*/
  /* global $sql3holderNum; 	*/
  /* global $sql3holderRowNbr;	*/

  private $agi; // A copy of the AGI class already running
  private $db;  // 'mysql', 'sqlite' or 'sqlite3'. Set in sql_database_connect, so we
		// know which commands to use. 

  // Public things that you might need to access

  public $errstr; 	// Holder for error string
  public $numrows; 	// Number of rows returned in the query

  // Just in case someone REALLY wants to work around all the sanity checks here, these
  // two variables are public, so you can use them if you REALLY must.
  public $dbtype;
  public $dbhandle; 

  function AGIDB($AGI=null) { 
	// This gets called when 'new AGIDB(..)' is run.

	if (!class_exists('AGI')) {
		// Running from the command line.. Hardcode everything, don't
		// use AGI
		$this->dbtype = 'sqlite3';
		$this->dbfile = '/var/lib/asterisk/freepbx.db';
		$this->dbhost = 'localhost';
		$this->dbuser = 'asterisk';
		$this->dbpass = 'asterisk';
		$this->dbname = 'asterisk';
		$this->agi = null;
	} else {
		$this->agi = $AGI; // Grab a copy of the AGI class.
		// Load up the variables we'll need later.
		$this->dbtype = $this->get_var("AMPDBENGINE");
		$this->dbhost = $this->get_var("AMPDBHOST");
		$this->dbuser = $this->get_var("AMPDBUSER");
		$this->dbpass = $this->get_var("AMPDBPASS");
		$this->dbfile = $this->get_var("AMPDBFILE");
		$this->dbname = $this->get_var("AMPDBNAME");
	}
	// Don't connect to the database on startup, as you want the AGI
	// to be up and running as fast as possible. Connect on the first
	// SQL command.
	$this->dbhandle = null;
  }

  function sql_database_connect() {
		$dbhandle = new mysqli($this->dbhost, $this->dbuser, $this->dbpass,$this->dbname);
		if (mysqli_connect_errno()) {
			$this->errstr = 'SEVERE: AGI could not connect to MySQL Database. '.mysqli_connect_error();
			debug ($this->errstr, 1);
			return null;
		}
		$this->debug("Connected to MySQL database OK.", 4);
		
		$this->errstr = null;
		$this->db = "mysql";
		return $dbhandle;
		
		
  }
  
  
  function sqlmultiquery($command, $type = "NONE", $override=false) {
  
  	$this->debug("Running SQL Command $command", 4);
  	// Ensure we're connected to the database.
  	if ($this->dbhandle == null) {
  		if (!$this->dbhandle = $this->sql_database_connect()) {
  			$this->debug('SEVERE: Unable to connect to database.', 1);
  			return false;
  		}
  	}
  
  	// Check for non-portable stuff.
  	if ($override != true) {
  		$result = $this->sql_check($command);
  		// sql_check returns a sanitized SQL command, or false if error.
  		if ($result == false) {
  			return false;
  		}
  	} 
  	 
  	$sqlresult = null;
  	$res = $this->dbhandle->multi_query( $command);
  	// Return the correct type.
  	if ($type == "NONE") {
  		return true;
  	}
  	
  	
  	if( $res ) {
  		$results = 0;
  		do {
  			if ($result = $this->dbhandle->store_result()) {
  				
  				$i=0;
  				$sqlresult = null;
			  	while($row = $result->fetch_assoc()) {
			  		$sqlresult[$i] =$row;
			  		$i++;
			  	}
  	 
  				$result->close();
  				
  			}
  		} while( $this->dbhandle->next_result() );
  	}
  	
  	
  	 
  	return $sqlresult;
  
  	 
  }
  
  function sql($command, $type = "NONE", $override=false) {
  
  	$this->debug("Running SQL Command $command", 4);
  	// Ensure we're connected to the database.
  	if ($this->dbhandle == null) {
  		if (!$this->dbhandle = $this->sql_database_connect()) {
  			$this->debug('SEVERE: Unable to connect to database.', 1);
  			return false;
  		}
  	}
  
  	// Check for non-portable stuff.
  	if ($override != true) {
  		$result = $this->sql_check($command);
  		// sql_check returns a sanitized SQL command, or false if error.
  		if ($result == false) {
  			return false;
  		}
  	} 
  	
  	$sqlresult = null;
  	$res = $this->dbhandle->query($command);
  	$this->numrows = mysqli_num_rows($res);
  			// Return the correct type.
  	if ($type == "NONE") {
  		return true;
  	}
  			
  			
  	$i=0;  			
  	while($row = $res->fetch_assoc()) {  			
  		$sqlresult[$i] =$row;  			
  		$i++;
  	}
  	
  	return $sqlresult;
 
  	
  }
  
			
	
  function get_var($value) {
        $r = $this->agi->get_variable( $value );

        if ($r['result'] == 1) {
                $result = $r['data'];
                return $result;
        }
        return '';
  }

  function sql_check($sql) {
	// Anything starting with ALTER is right out. 
	if (preg_match('/^ALTER/', $sql)) {
		$this->debug("SEVERE PROGRAMMING ERROR: Do not use ALTER in SQL Queries. ".
			"Use SQL Class functions. ABORTING.", 0);
		exit;
	}
	// Make sure that at least one pair of backticks has been found.
	if (!preg_match('/\`.+\`/', $sql)) {
		$this->debug("SEVERE PROGRAMMING ERROR: For portability, COLUMNS must be ".
			"surrounded by BACK TICKS (`), yet none were found. Continuing.", 0);
	}
	if (!preg_match('/\'.+\'/', $sql)) {
		$this->debug("SEVERE PROGRAMMING ERROR: For portability, FIELDS must be ".
			"surrounded by SINGLE QUOTES ('), yet none were found. Continuing.", 0);
	}
	return $sql;
  }

  
	
  function debug($string, $level=3) {
	if (class_exists('AGI')) {
        	$this->agi->verbose($string, $level);
	} else {
		print "$string\n";
	}
  }

  
		

}


?>
